package com.baymax.springboot.cli.plugins.mybatis;

import com.baymax.springboot.cli.generator.CodeGenerator;
import com.baymax.springboot.cli.generator.component.meta.TableMeta;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

import java.util.List;

/**
 * 此插件配置在generatorConfig.xml中
 */
public class ColumnListPlugin extends PluginAdapter {

    /**
     * 重写 validate 返回true，插件才能生效
     * @param list
     * @return
     */
    @Override
    public boolean validate(List<String> list) {
        return true;
    }

    /**
     * 为每个Example类添加limit和offset属性已经set、get方法
     */
    @Override
    public boolean modelExampleClassGenerated(TopLevelClass topLevelClass,
                                              IntrospectedTable introspectedTable) {

        TableMeta tableMeta = new TableMeta();
        String tableName = introspectedTable.getTableConfiguration().getTableName();
        System.out.println("table name is:" + tableName);

        List<IntrospectedColumn> allColumns = introspectedTable.getAllColumns();
        for(IntrospectedColumn column : allColumns) {
            System.out.println("column name is:" + column.getActualColumnName());
            tableMeta.put(tableName, column.getActualColumnName());
        }

        CodeGenerator.tableMetaList.add(tableMeta);

        FullyQualifiedJavaType arrayType = new FullyQualifiedJavaType("String[]");
        FullyQualifiedJavaType stringType = new FullyQualifiedJavaType("String");

        FullyQualifiedJavaType type = new FullyQualifiedJavaType(
                introspectedTable.getMyBatis3JavaMapperType());

        /**
         * 新增一个limit属性
         */
        Field limit = new Field("dynamicColumns", type);
        limit.setVisibility(JavaVisibility.PRIVATE);
        limit.setType(arrayType);
        topLevelClass.addField(limit);

        /**
         * 新增一个setLimit方法
         */
        Method setLimit = new Method("setDynamicColumns");
        setLimit.setVisibility(JavaVisibility.PUBLIC);
        setLimit.addParameter(new Parameter(arrayType, "dynamicColumns"));
        setLimit.addBodyLine("this.dynamicColumns = dynamicColumns;");
        topLevelClass.addMethod(setLimit);

        /**
         * 新增一个getLimit方法
         */
        Method getLimit = new Method("getDynamicColumns");
        getLimit.setVisibility(JavaVisibility.PUBLIC);
        getLimit.setReturnType(stringType);
        /**
         * String.join()是JDK8新增方法
         */
        getLimit.addBodyLine("return String.join(\",\", this.dynamicColumns);");
        topLevelClass.addMethod(getLimit);

        return true;
    }

    /**
     * 默认生成：
     * <sql id="Base_Column_List">
     *     id, gmt_created, creator, gmt_modified, modifier, is_deleted, `name`, age, salary,
     *     year_of_working, tags, version
     * </sql>
     *
     * @param element
     * @param introspectedTable
     * @return
     */
    @Override
    public boolean sqlMapBaseColumnListElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {

        /**
         * 默认会把这个表的所有字段都生成，我想使用dynamic_columns，那么就只能先全部清了
         */
        element.getElements().clear();//清理掉默认生成的内容
        element.addElement(new TextElement("${dynamicColumns}"));
        return super.sqlMapBaseColumnListElementGenerated(element,
                introspectedTable);
    }

    @Override
    public boolean sqlMapBlobColumnListElementGenerated(XmlElement element, IntrospectedTable introspectedTable){
        //直接不生成此标签
        return false;
    }

    @Override
    public boolean sqlMapSelectByExampleWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        //直接不生成此标签
        return false;
    }

    @Override
    public boolean clientSelectByExampleWithBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        //直接不生成此标签
        return false;
    }

    @Override
    public boolean clientUpdateByExampleWithBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientUpdateByExampleWithoutBLOBsMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean sqlMapUpdateByExampleWithBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean sqlMapUpdateByExampleWithoutBLOBsElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean sqlMapSelectByPrimaryKeyElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }

    @Override
    public boolean clientSelectByPrimaryKeyMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        return false;
    }
}
